package com.longyu.crowd.mvc.config;

import com.google.gson.Gson;
import com.longyu.crowd.constant.CrowdConstant;
import com.longyu.crowd.exception.LoginAcctAlreadyInUserException;
import com.longyu.crowd.exception.LoginAcctAlreadyInUserForUpdateException;
import com.longyu.crowd.exception.LoginFailedException;
import com.longyu.crowd.util.CrowdUtil;
import com.longyu.crowd.util.ResultEntity;
import com.sun.org.apache.regexp.internal.RE;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import sun.plugin.javascript.JSClassLoader;
import sun.plugin2.message.Message;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ControllerAdvice 表示当前这个了类是一个基于注解的 异常处理器类
 */
@EnableWebMvc
@ControllerAdvice
public class CrowdExceptionResolver {
    @ExceptionHandler(value = LoginAcctAlreadyInUserForUpdateException.class)
    public ModelAndView resolveLoginAcctAlreadyInUserForUpdateException(LoginAcctAlreadyInUserForUpdateException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {

        String viewName = "system-error";
        return commonResolve(viewName, exception, request, response);
    }

    @ExceptionHandler(value = LoginAcctAlreadyInUserException.class)
    public ModelAndView resolveLoginAcctAlreadyInUserException(LoginAcctAlreadyInUserException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {

        String viewName = "admin-add";
        return commonResolve(viewName,exception,request,response);
    }

    @ExceptionHandler(value = LoginFailedException.class)
    public ModelAndView resolveLoginFailedException(LoginFailedException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {

        String viewName = "admin-login";
        return commonResolve(viewName,exception,request,response);
    }

    @ExceptionHandler(value = ArithmeticException.class)
    public ModelAndView resolveMathException(ArithmeticException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {

        String viewName = "system-error";
        return commonResolve(viewName,exception,request,response);
    }

                                                            // 实际捕获到的异常类型         // 当前请求对象
    private ModelAndView commonResolve(String viewName,Exception exception,HttpServletRequest request,HttpServletResponse response) throws IOException {
        // 1、判断当前请求类型
        boolean judgeResult = CrowdUtil.judgeRequestType(request);

        // 2、如果是一个Ajax请求
        if (judgeResult) {

            // 3、创建ResultEntity对象
            ResultEntity<Object> resultEntity = ResultEntity.failed(exception.getMessage());

            // 4、创建Gson对象
            Gson gson = new Gson();

            // 5、将ResultEntity对象转换为JSON字符串
            String json = gson.toJson(resultEntity);

            // 6、将JSON字符串作为响应体返回给浏览器
            response.getWriter().write(json);

            // 7、由于上面已经通过原生的response对象返回了响应，所以不提供ModelAndView对象
            return null;
        }

        // 8、如果不是Ajax请求，则创建ModelAndView对象
        ModelAndView modelAndView = new ModelAndView();

        // 9、将Exception对象存入ModelAndView
        modelAndView.addObject(CrowdConstant.ATTR_NAME_EXCEPTION,exception);

        // 10、设置对应的视图名称
        modelAndView.setViewName(viewName);

        // 11、返回ModelAndView对象
        return modelAndView;
    }



    // @ExceptionHandler将一个具体的异常类型和一个方法关联起来
    @ExceptionHandler(value = NullPointerException.class)
    public ModelAndView resolveNullPointerException(NullPointerException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewName = "error";
        return commonResolve(viewName,exception,request,response);
    }

}
